#pragma once

#include "ColligereSingleton.hpp"

namespace col {

////////////////////////////////////////////////
// ColligereConfigVariable
////////////////////////////////////////////////

class ConfigVariable
{
public:
	ConfigVariable() : mId(0), mType(0) { }
	ConfigVariable ( wxUint32 id, const wxString &rVariable, 
		const wxString &rDescr, wxUint32 varType );

	enum Id
	{
		AskBeforeApplyingValues, AskBeforeExiting, 
		AudioDatabaseWxAuiSettings,
		AutoVacuumDatabase,
		CaseSensitiveSearchChecked, CurrentColligereVersion,
		DatabaseCompressionLevel, DatabaseSyncType, DefaultDatabase,
		DumpLogToFileOnExit, 
		DisableAutoComplete,
		FreeDbUserEmail, FreeDbServerAddr, FreeDbAutoSetFormatToCd,
		IsFirstAppExecution, IsMainFrameMaximized,
		Language, LastOpenedDatabaseDir, LastSavedLogDir,
		LogDialogPosition, LogDialogSize, 
		MainFramePosition, MainFrameSize, MainFrameWxAuiSettings, 
		SaveDatabaseOnClose, SaveLayoutOnExit, 
		ShowToolTips,
		SearchTerms,
		UseRegExSearchChecked
	};

	enum Type { Private = 1, User };

	bool operator == ( wxUint32 id ) const;
	bool operator < ( wxUint32 id ) const;

	const wxString &GetName() const;
	const wxString &GetDescription() const;

	wxUint32 GetId() const;
	wxUint32 GetType() const;
private:
	wxUint32 mId, mType;
	wxString mDescr, mVar, mGuiCat;
};

typedef std::deque < const ConfigVariable > ConfigVariableDeque;

////////////////////////////////////////////////
// ColligereConfigHandler
////////////////////////////////////////////////

class ConfigHandler : public Singleton < ConfigHandler >
{
public:
	virtual ~ConfigHandler();

	bool GetVar ( wxUint32 varId, ConfigVariable &rTo ) const;

	const wxString GetValue ( wxUint32 varId ) const;
	bool GetValue ( wxUint32 varId, long &rVal ) const;
	
	bool SetValue ( wxUint32 varId, long value );
	bool SetValue ( wxUint32 varId, const wxString &rValue );

	const wxPoint GetPosition ( wxUint32 varId ) const;
	const wxSize GetSize ( wxUint32 varId ) const;

	bool SetPosition ( wxUint32 varId, const wxPoint &rPos );
	bool SetSize ( wxUint32 varId, const wxSize &rSize );
	
	bool IsEnabled ( wxUint32 varId ) const;
	bool Exists ( wxUint32 varId ) const;

	void WriteDefaults ( bool forceWrite = false );

	const ConfigVariableDeque &GetConfigVariables() const;
	bool DeleteAll();

	void LoadFileHistory ( wxFileHistory &rHistory ) const;
	void SaveFileHistory ( wxFileHistory &rHistory );

	void LoadLastDirectory ( wxUint32 dirVarId, wxFileDialog &rToDlg ) const;
private:
	ConfigHandler();

	friend class Singleton < ConfigHandler >;

	void WriteDefaultsIfMissing();

	bool SetValueIfMissing ( wxUint32 varId, long value );
	bool SetValueIfMissing ( wxUint32 varId, const wxString &rValue );

	void CreateUsrModifiableVar ( wxUint32 id, const wxString &rName, 
		const wxString &rDescr = wxEmptyString );
	void CreatePrivateVar ( wxUint32 id, const wxString &rName );

	const wxString &ConvertVarIdToVarName ( wxUint32 varId ) const;

	bool SetSize ( const wxString &rVariable, const wxSize &rSize );
	bool SetPosition ( const wxString &rVariable, const wxPoint &rPos );
	bool SetValue ( const wxString &rVarName, long value );
	bool SetValue ( const wxString &rVarName, const wxString &rValue );

	const wxString GetValue ( const wxString &rVariable ) const;
	
	bool GetValue ( const wxString &rVarName, long &rValue ) const;
	bool GetValue ( const wxString &rVarName, wxString &rValue ) const;
	
	//! Returns the value of the variable parsed as a wxSize.
	const wxSize GetSize ( const wxString &rVariable ) const;

	//! Returns the value of the variable parsed as a wxPoint.
	const wxPoint GetPosition ( const wxString &rVariable ) const;

	//! Returns true if the variable exists and has the value of 1, false otherwise.
	bool IsEnabled ( const wxString &rVariable ) const;

	// A deque of valid config variables.
	ConfigVariableDeque mCfgVars;
	//! The actual config handler.
	wxConfigBase *mpCfg;
};

}